export class Snake {
  element: HTMLElement
  head: HTMLElement
  bodies: HTMLCollection // 包括蛇头

  constructor() {
    this.element = document.getElementById('snake')!
    this.head = document.querySelector('#snake>div')!
    this.bodies = this.element.getElementsByTagName('div')
  }

  // 蛇头坐标
  get X() {
    return this.head.offsetLeft
  }
  get Y() {
    return this.head.offsetTop
  }
  set X(value: number) {
    if (this.X === value) return

    if (value < 0 || value > 290) throw new Error('蛇撞墙了')

    // 判断蛇掉头
    if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetLeft === value) {
      // 禁止掉头 反方向走
      if (value > this.X) value = this.X - 10
      else value = this.X + 10
    }

    this.moveBody()
    this.head.style.left = value + 'px'
    this.checkBodyCollision()
  }
  set Y(value: number) {
    if (this.Y === value) return

    if (value < 0 || value > 290) throw new Error('蛇撞墙了')

    // 判断蛇掉头
    if (this.bodies[1] && (this.bodies[1] as HTMLElement).offsetTop === value) {
      // 禁止掉头 反方向走
      if (value > this.Y) value = this.Y - 10
      else value = this.Y + 10
    }

    this.moveBody()
    this.head.style.top = value + 'px'
    this.checkBodyCollision()
  }

  // 增加蛇身
  addBody() {
    this.element.insertAdjacentHTML('beforeend', '<div/>')
  }

  moveBody() {
    for (let i = this.bodies.length - 1; i > 0; i--) {

      let X = (this.bodies[i - 1] as HTMLElement).offsetLeft;
      let Y = (this.bodies[i - 1] as HTMLElement).offsetTop;

      (this.bodies[i] as HTMLElement).style.left = X + 'px';
      (this.bodies[i] as HTMLElement).style.top = Y + 'px';
    }
  }

  checkBodyCollision() {
    // 检查蛇头与身体是否碰撞
    for (let i = 4; i < this.bodies.length; i++) {
      if (this.X === (this.bodies[i] as HTMLElement).offsetLeft && this.Y === (this.bodies[i] as HTMLElement).offsetTop) throw new Error('蛇打结了')
    }
  }
}
